#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include "syscall.h"
#include <assert.h>

static int evtdev = -1;
static int fbdev = -1;
//static int screen_w = 320, screen_h = 0;
static int screen_w, screen_h;

uint32_t NDL_GetTicks() {
	struct timeval time;
	struct timezone nouse;
	gettimeofday(&time,&nouse);
	return time.tv_usec;
}

int NDL_PollEvent(char *buf, int len) {
	int fp = open("/dev/event","r");
  int ret = read(fp, buf, len);
	close(fp);
	if((ret !=0)&&(strncmp(buf,"ku:",3)==0||strncmp(buf,"kd:",3)==0))return 1;
	else return 0;
}

//get the value from the procfs according to the key
//if_assert in this func, you should print the buf to check the file's correctness
size_t get_value_from_key(const char*name,char*buf){
	int name_len = strlen(name);
	int buf_len = strlen(buf);
	long ret;
	char *pt = buf;
	for(pt;pt < buf + buf_len;pt++){
		if(strncmp(name,pt,name_len)==0){
			pt += name_len;	
			for(pt;pt<buf+buf_len;pt++){
				if(*pt == ':')break;
			}	
			assert(pt < buf_len+buf-1);	//the ":" is not the last char
			char **endptr;
			ret = strtol(pt+1,endptr,10);
			if (endptr == NULL)return ret;
			else{
				assert(*endptr > pt +1);
				return ret;
			}
		}
	}
	assert(pt <buf_len + buf);
	return -1;
}

static size_t width = 0;
static size_t height = 0;
void NDL_OpenCanvas(int *w, int *h) {
	char buf[64] = {};
	int fp = open("/proc/dispinfo","r");
  read(fp,buf,64);
	close(fp);
	screen_w = get_value_from_key("WIDTH",buf);
	screen_h = get_value_from_key("HEIGHT",buf);
	assert(screen_w >= *w && screen_h >= *h);
	if(*w ==0 && *h ==0){
	 width = screen_w;
	 height = screen_h;
	}
	else{
		width = *w;
		height = *h;
	}
  if (getenv("NWM_APP")) {
    int fbctl = 4;
    fbdev = 5;
    screen_w = *w; screen_h = *h;
    char buf[64];
    int len = sprintf(buf, "%d %d", screen_w, screen_h);
    // let NWM resize the window and create the frame buffer
    write(fbctl, buf, len);
    while (1) {
      // 3 = evtdev
      int nread = read(3, buf, sizeof(buf) - 1);
      if (nread <= 0) continue;
      buf[nread] = '\0';
      if (strcmp(buf, "mmap ok") == 0) break;
    }
    close(fbctl);
  }
}

void NDL_DrawRect(uint32_t *pixels, int x, int y, int w, int h) {
	int fp = open("/dev/fb","r");
	//画布只给定了宽和高，没有给坐标，将其定在中心
	assert((width != 0) && (height !=0)); //usually caused by not use NDL_OpenCanvas
	//pixels中存放着画布中从头开始的数据，只要将要求的xywh中的数更新到显存
	//for(int i=0;i<h-y;i++){
	char buf[64] = {};
	int fp1 = open("/proc/dispinfo","r");
  read(fp1,buf,64);
	close(fp1);
	screen_w = get_value_from_key("WIDTH",buf);
	screen_h = get_value_from_key("HEIGHT",buf);
  assert(screen_w!=0);
	for(int i=0;i<h;i++){
			lseek(fp,(i+y)*screen_w+x,0);
			write(fp,pixels+(i+y)*width+x,4*(w));	
		}
	close(fp);
	}
void NDL_OpenAudio(int freq, int channels, int samples) {
}

void NDL_CloseAudio() {
}

int NDL_PlayAudio(void *buf, int len) {
  return 0;
}

int NDL_QueryAudio() {
  return 0;
}

int NDL_Init(uint32_t flags) {
  if (getenv("NWM_APP")) {
    evtdev = 3;
  }
  return 0;
}

void NDL_Quit() {
}
